import request from '@/axios'
import { FormItemRule, UploadRawFile } from "element-plus"
import { Arrayable } from "element-plus/es/utils"
import { check, checkResultPage, Page, ResultPage } from "./baseModel"

// 搜索实体
export interface ProductSearch {
    name: string | undefined
    categoryId: string | undefined
    minPrice: number | undefined
    maxPrice: number | undefined
    status: boolean | undefined
}

// 商品表单上传数据
export interface ProductForm {
    id: string
    name: string
    categoryId: string
    description: string
    currentPrice: number
    originalPrice: number
    stock: number
    unit: string
    image: UploadRawFile | undefined | string
    status: boolean
}

// 商品实体
export interface Product {
    id: string
    name: string
    description: string
    categoryName: string
    categoryId: string
    currentPrice: number
    originalPrice: number
    monthlySales: number
    stock: number
    status: boolean
    unit: string
    image: string
    createTime: string
    tags: string
}

// 获取初始化的提交商品表单对象
export function getInitProductForm() {
    return {
        id: '',
        name: '',
        categoryId: '',
        description: '',
        currentPrice: 0,
        originalPrice: 0,
        stock: 0,
        unit: '件',
        image: undefined,
        status: true
    }
}

// 获取初始化的商品搜索对象
export function getInitProductSearch() {
    return {
        name: undefined,
        categoryId: undefined,
        minPrice: undefined,
        maxPrice: undefined,
        status: undefined,
    }
}

// 表单验证规则
export const productFormRules: Partial<Record<string, Arrayable<FormItemRule>>> = {
    name: [
        { required: true, message: '请输入商品名称', trigger: 'blur' },
        { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
    ],
    categoryId: [
        { required: true, message: '请选择商品分类', trigger: 'change' }
    ],
    description: [
        { required: true, message: '请输入商品描述', trigger: 'blur' },
        { min: 5, max: 200, message: '长度在 5 到 200 个字符', trigger: 'blur' }
    ],
    currentPrice: [
        { required: true, message: '请输入现价', trigger: 'blur' },
        { type: 'number', min: 0, message: '价格必须大于0', trigger: 'blur' }
    ],
    originalPrice: [
        { required: true, message: '请输入原价', trigger: 'blur' },
        { type: 'number', min: 0, message: '价格必须大于0', trigger: 'blur' }
    ],
    stock: [
        { required: true, message: '请输入库存', trigger: 'blur' },
        { type: 'number', min: 0, message: '库存必须大于0', trigger: 'blur' }
    ],
    unit: [
        { required: true, message: '请输入商品单位', trigger: 'blur' },
        { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' }
    ],
    image: [
        { required: true, message: '请上传商品图片', trigger: 'change' }
    ]
}

/**
 * 用于发起商品请求的 API
 *  static pagingSearch(search, page)       分页获取数据
 *  static create(Form)                     新增数据
 *  static deleteById(id)                   删除数据
 *  static updateById(Form, id)             修改数据
 *  addTags(form)                           新增标签 
 *  deleteTags(id, tags)                    删除标签
 */
export class ProductApi {

    static baseUrl = '/product'

    // 分页获取数据
    static async pagingSearch(search: ProductSearch, page: Page): Promise<ResultPage<Product>> {
        try {
            const response = await request.get(
                `${this.baseUrl}/search`,
                {params: {...search, ...page}, data: {loading: '加载商品数据'}}
            )
            return checkResultPage(response) as ResultPage<Product>
        } 
        catch (error: any) { throw error }
    }

    // 新增数据
    static async create(from: ProductForm): Promise<Product> {
        try {
            let data = new FormData()
            for (let item in from) {data.append(item, from[item])}
            const response = await request.post(
                this.baseUrl, 
                data, 
                {headers: {'Content-Type': 'multipart/form-data'}}
            )
            return check(response) as Product
        }
        catch (error: any) { throw error }
    }

    // 删除数据
    static async deleteById(id: string) {
        try {
            const response = await request.delete(
                `${this.baseUrl}/${id}`,
                {data: {loading: '删除商品中'}}
            )
            check(response)
        }
        catch (error: any) { throw error }
    }

    // 修改数据
    static async updateById(form: ProductForm, id: string): Promise<Product> {
        try {
            let data = new FormData()
            for (let item in form) {data.append(item, form[item])}

            if (form.image == undefined || typeof form.image == 'string') 
                data.delete("image")

            const response = await request.put(
                `${this.baseUrl}/${id}`,
                data,
                {headers: {'Content-Type': 'multipart/form-data'}}
            )
            return check(response) as Product
        } 
        catch (error: any) { throw error }
    }

    // 新增商品标签
    static async addTags(params: any): Promise<Product> {
        try {
            const response = await request.put(
                this.baseUrl + `/tags?id=${params.id}&tags=${params.tags}`,
                {data: {loading: '新增标签'}}
            )
            return check(response) as Product
        } 
        catch (error: any) { throw error }
    }

    // 删除商品标签
    static async deleteTags(id: string, tag: string) {
        try {
            const response = await request.delete(
                this.baseUrl + `/tags?id=${id}&tags=${tag}`,
                {data: {loading: '删除标签'}}
            )
            return check(response) as Product
        }
        catch (error: any) { throw error }
    }

}